#pragma once

// note:枚举类的使用
enum class UserPermission :int {
	FileRead = (1 << 0),    /**< Download files */
	FileWrite = (1 << 1),	/**< Upload files as new files */
	FileAppend = (1 << 2),	/**< Upload files that get appended to existing files */
	FileDelete = (1 << 3),	/**< Delete existing files or overwrite an existing file */
	FileRename = (1 << 4),	/**< Rename existing files */

	DirList = (1 << 5),		/**< Retrieve the content of directories */
	DirCreate = (1 << 6),   /**< Create new directories */
	DirDelete = (1 << 7),   /**< Delete existing directories */
	DirRename = (1 << 8),   /**< Rename existing directories */

	All = (FileRead | FileWrite | FileAppend | FileDelete | FileRename | DirList | DirCreate | DirDelete | DirRename),
	ReadOnly = (FileRead | DirList),
	None = 0
};


inline UserPermission operator~(UserPermission p) { return static_cast<UserPermission>(~static_cast<int>(p)); }
inline UserPermission operator&(UserPermission p1, UserPermission p2) {	return static_cast<UserPermission>(static_cast<int>(p1) & static_cast<int>(p2));}
inline UserPermission operator|(UserPermission p1, UserPermission p2) {	return static_cast<UserPermission>(static_cast<int>(p1) | static_cast<int>(p2));}
inline UserPermission operator^(UserPermission p1, UserPermission p2) { return static_cast<UserPermission>(static_cast<int>(p1) ^ static_cast<int>(p2)); }
inline UserPermission& operator&=(UserPermission& p1, UserPermission& p2) { return reinterpret_cast<UserPermission&>(reinterpret_cast<int&>(p1) &= static_cast<int>(p2)); }
inline UserPermission& operator|=(UserPermission& p1, UserPermission& p2) { return reinterpret_cast<UserPermission&>(reinterpret_cast<int&>(p1) |= static_cast<int>(p2)); }
inline UserPermission& operator^=(UserPermission& p1, UserPermission& p2) { return reinterpret_cast<UserPermission&>(reinterpret_cast<int&>(p1) ^= static_cast<int>(p2)); }

/*
	note: 枚举类的优雅实现，参考自fineftp
	 enum class Permission : int
	  {
		FileRead   = (1 << 0), 
		FileWrite  = (1 << 1), 
		FileAppend = (1 << 2), 
		FileDelete = (1 << 3), 
		FileRename = (1 << 4), 

		DirList    = (1 << 5), 
		DirCreate  = (1 << 6), 
		DirDelete  = (1 << 7), 
		DirRename  = (1 << 8), 

		All      = (FileRead | FileWrite | FileAppend | FileDelete | FileRename | DirList | DirCreate | DirDelete | DirRename),
		ReadOnly = (FileRead | DirList),
		None     = 0
	  };

	  inline Permission operator~   (Permission a)                { return static_cast<Permission>(~static_cast<int>(a)); }
	  inline Permission operator|   (Permission a, Permission b)  { return static_cast<Permission>(static_cast<int>(a) | static_cast<int>(b)); }
	  inline Permission operator&   (Permission a, Permission b)  { return static_cast<Permission>(static_cast<int>(a) & static_cast<int>(b)); }
	  inline Permission operator^   (Permission a, Permission b)  { return static_cast<Permission>(static_cast<int>(a) ^ static_cast<int>(b)); }
	  inline Permission& operator|= (Permission& a, Permission b) { return reinterpret_cast<Permission&>(reinterpret_cast<int&>(a) |= static_cast<int>(b)); }
	  inline Permission& operator&= (Permission& a, Permission b) { return reinterpret_cast<Permission&>(reinterpret_cast<int&>(a) &= static_cast<int>(b)); }
	  inline Permission& operator^= (Permission& a, Permission b) { return reinterpret_cast<Permission&>(reinterpret_cast<int&>(a) ^= static_cast<int>(b)); }
*/